/**
 * Copyright 2009 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * 	http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.xume.raob.core;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.xume.raob.api.ConstructorArgument;

/**
 * @author Johan Siebens
 */
public class ConstructorArguments {

	private Map<Method, ConstructorArgument> constructorArguments = new HashMap<Method, ConstructorArgument>();

	private List<Boolean> constructorsArgsIndexes = new GrowthList();

	public void addConstructorArgument(Method method, ConstructorArgument constructorArgument) {
		this.constructorArguments.put(method, constructorArgument);
		this.constructorsArgsIndexes.set(constructorArgument.getIndex(), true);
	}

	public ConstructorArgument getConstructorArgument(Method method) {
		return this.constructorArguments.get(method);
	}

	public boolean isConstructorArgumentMethod(Method method) {
		return this.constructorArguments.containsKey(method);
	}

	public List<Integer> listMissingIndexes() {
		List<Integer> missingIndexes = new ArrayList<Integer>();
		for (int i = 0; i < constructorsArgsIndexes.size(); i++) {
			if (constructorsArgsIndexes.get(i) == null) {
				missingIndexes.add(i);
			}
		}
		return missingIndexes;
	}

	public int numberOfArguments() {
		return this.constructorArguments.size();
	}

	public Collection<ConstructorArgument> values() {
		return constructorArguments.values();
	}

	private static class GrowthList extends LinkedList<Boolean> {

		private static final long serialVersionUID = -1055083990734130822L;

		@Override
		public Boolean set(int index, Boolean element) {
			int size = super.size();
			if (index >= size) {
				super.addAll(Arrays.asList(new Boolean[(index - size) + 1]));
			}
			return super.set(index, element);
		}

	}

}
